package com.example.mall.service.impl;

import com.alibaba.fastjson.JSON;
import com.example.mall.constants.BaseConstants;
import com.example.mall.dto.SMSSend2MQ;
import com.example.mall.dto.SMSSendParamDto;
import com.example.mall.exception.ErrorEnumCode;
import com.example.mall.exception.GlobalCustomerException;
import com.example.mall.service.IVerifyCodeService;
import com.example.mall.util.StrUtils;
import com.example.mall.util.VerifyCodeUtils;
import com.example.mall.vo.VerifyCode2Cache;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.concurrent.TimeUnit;

/**
 * @Author: xxxliu
 * @CreateTime: 2025-04-29
 * @Version: 1.0
 */
@Service
@Slf4j
public class VerifyCodeServiceImpl implements IVerifyCodeService {

    @Autowired
    private RedisTemplate<Object, Object> redisTemplate;

    @Autowired
    private RocketMQTemplate rocketMQTemplate;

    /*
     * Description：图片验证码
     * 1.判断参数
     * 2.创建一个图片验证码值
     * 3.把图片验证码值存储到Redis，以传入的key为key
     * 4.把验证码值画到图片中
     * 5.把图片使用base64编码成字符串
     * 6.返回base64编码成字符串
     * @param imageCodeKey
     * @return:
     * @Author:  xxxli
     * @date:  2025/4/29 15:20
     */

    @Override
    public String createImageCode(String imageCodeKey) {
        //判断是否有验证码
        if (StringUtils.isEmpty(imageCodeKey)){
            throw  new GlobalCustomerException(ErrorEnumCode.COMMON_SMS_CODE_ERROR);
        }
        //随机生成四位验证码
        String imgCode= VerifyCodeUtils.generateVerifyCode(4,VerifyCodeUtils.VERIFY_CODES);
        //将验证码存入redis
        redisTemplate.opsForValue().set(imageCodeKey+":"+imgCode,imgCode,60, TimeUnit.SECONDS);
        //使用base64加密
        String base64Img = VerifyCodeUtils.verifyCode(137, 39, imgCode);
        System.out.println("Key: " + (imageCodeKey + ":" + imgCode));
        System.out.println("Value: " + imgCode);
        return base64Img;
    }

    /*
     * @Description:
     * 1.验证参数
     * 2.校验图片验证码
     * 2.1.使用传入的key从redis获取图片验证码
     * 2.2.redis中的图片验证码和传入的图片验证码比较
     * 3.判断是否有一个未使用的手机验证码
     * 4.如果有
     * 4.1.从Redis获取上一次的手机验证码发送记录
     * 4.2.判断上一次发送时间和当前发送时间是否过了重发时间
     * 4.3.如果没过报错，过了就获取上一次手机验证码的值,
     * 4.4.把上一次的验证码重发一次
     * 4.5.重新存储一次验证码发送记录
     * 5.如果没有
     * 5.1.创建一个手机验证码
     * 5.2.存储手机验证码存储到Redis
     * 5.3.发送短信验证码
     * 6.数据库保存验证码发送记录
     * @param dto
     * @return:
     * @Author:  xxxli
     * @date:  2025/4/29 15:21
     */

    @Override
    public void sendSmsCode(SMSSendParamDto dto) {
        String imageCode = dto.getImageCode();
        String imageCodeKey = dto.getImageCodeKey();
        String mobile = dto.getMobile();
        //校验参数
        if(StringUtils.isEmpty(imageCode)){
            throw new GlobalCustomerException(ErrorEnumCode.COMMON_IMAGE_CODE_EMPTY);
        }
        if(StringUtils.isEmpty(imageCodeKey)){
            throw new GlobalCustomerException(ErrorEnumCode.COMMON_IMAGE_CODE_KEY_EMPTY);
        }
        if(StringUtils.isEmpty(mobile)){
            throw new GlobalCustomerException(ErrorEnumCode.COMMON_PHONE_EMPTY);
        }
        //校验图片验证码
        String o = (String) redisTemplate.opsForValue().get(imageCodeKey + ":" + imageCode);
        if(StringUtils.isEmpty(o)){
            throw new GlobalCustomerException(ErrorEnumCode.COMMON_IMAGE_CODE_ERROR);
        }else {
            //redis中的图片验证码和传入的图片验证码比较
            if(!StringUtils.equals(o,imageCode)){
                throw new GlobalCustomerException(ErrorEnumCode.COMMON_SMS_CODE_ERROR);
            }
            //手机验证码
            String smsCode = null;
            //当前时间
            Date now  = new Date();
            //判断是否有一个未使用的手机验证码
            VerifyCode2Cache lastSendSms = (VerifyCode2Cache) redisTemplate.opsForValue().get(BaseConstants.SMS_PHONE_KEY+mobile);
            //如果有
            if(lastSendSms != null){
                //上一次发送时间
                Date sendTime = lastSendSms.getSendTime();
                if( (now.getTime() - sendTime.getTime())  / 1000 < 60){
                    throw new GlobalCustomerException(ErrorEnumCode.COMMON_SMS_CODE_QUICKLY);
                }
                //如果没过报错，过了就获取上一次手机验证码的值,
                smsCode = lastSendSms.getCode();
                //重新存储一次验证码发送记录
                //把上一次的验证码重发一次
            }else{
                //如果没有
                //创建一个手机验证码
                smsCode = StrUtils.getRandomString(6);
            }
            //存储手机验证码存储到Redis
            redisTemplate.opsForValue().set(BaseConstants.SMS_PHONE_KEY+mobile, new VerifyCode2Cache(smsCode,mobile, now),
                    10*60,TimeUnit.SECONDS);

            String smsContent =  String.format("您的验证码为 %s ,请在 %s 分钟内使用", smsCode, 10);
            log.info(smsCode);
            //手机号
            SendResult result = rocketMQTemplate.syncSend(
                    BaseConstants.Topic.TOPIC_MESSAGE + ":" + BaseConstants.Topic.TAGS_SMS_NAME,
                    JSON.toJSONString(new SMSSend2MQ(null, "注册验证码", smsContent))
            );
            log.info("短信发送到MQ",result);
        }
    }
}
